﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Security.Cryptography;
using BitcoinLibrary;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace TestBitcoinLibrary
{
    class Program
    {
        static void Main(string[] args)
        {
#if true
            // TODO: see http://code.google.com/p/bitcoinj/wiki/GettingStarted
            NetworkParameters param = NetworkParameters.testNet();

            // Creates a brand new keypair.
            ECKey key = new ECKey();

            // Gets the raw public key bytes. You don't normally need this.
            byte[] publicKey = key.getPubKey();

            // Gets the address corresponding to the public key.
            Address addr = key.toAddress(param);
            Debug.WriteLine(addr.ToString());   // ->  1HwBZk111V4eEEC4BcN8fZd3RVifig2WjY

            // Try to read the wallet from storage, create a new one if not possible.
            Wallet wallet;
            FileStream walletFile;
            try 
            {
                walletFile = new FileStream("wallet.dat", FileMode.Open);
                wallet = Wallet.loadFromFile(walletFile);
            } 
            catch (Exception ex) 
            {
                walletFile = new FileStream("wallet.dat", FileMode.Create);
                wallet = new Wallet(param);
                wallet.keychain.Add(new ECKey());
                wallet.saveToFile(walletFile);
            }
            // Fetch the first key in the wallet (should be the only key).
            key = wallet.keychain[0];

            var localIp = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).First();
            NetworkConnection conn = new NetworkConnection(localIp, param, 0 /* bestInKeychain */, 0);
            BlockStore blockStore = new BlockStore();
            BlockChain chain = new BlockChain(param, wallet, blockStore);
            Peer peer = new Peer(param, conn, chain);
            peer.start();

            Console.ReadLine();
#else
            BitcoinLibrary.Bitcoin btc = new BitcoinLibrary.Bitcoin();

            btc.TestHash();
            //BitcoinLibrary.Bitcoin_header_checksum test = new BitcoinLibrary.Bitcoin_header_checksum();
            //test.Command = "getaddr";
            //test.Payload = new byte[] { };
            //byte[] data = test.Pack();

            BitcoinLibrary.NetworkAddress addr = new BitcoinLibrary.NetworkAddress();
            addr.GetBytes("192.168.0.112");

            bool getblocksSent = false;
            //btc.Test();
            btc.Connect();
            //btc.SendVersion();
            do
            {
                //Console.WriteLine("Press ENTER to check for new input");
                //Console.ReadLine();
                Thread.Sleep(100);
                Console.Clear();
                Console.WriteLine(DateTime.Now.ToString());
                btc.UpdatePeers();
                Console.WriteLine("Number of peers = " + btc.Peers.Length + "\t\tNumber of blocks: " + btc.blockChain.Keys.Count);
                //if (Console.ReadKey().Modifiers == ConsoleModifiers.Shift)
                //{
                //    Console.WriteLine("Testing...");
                //    btc.Test();
                //    Thread.Sleep(5000);
                //}
                //if (!getblocksSent && (btc.Peers.Where(p => p.IsConnected).Count() > 5))
                //{
                //    getblocksSent = true;
                //    btc.Test();
                //    Console.WriteLine("*** Test sent");
                //}
                //bool ff = false;
                //if (btc.Peers.Count() > 30) ff = true;
                //if (ff)
                //{
                var list = btc.Peers.Where(p => p.IsConnected).Select(peer => peer.Address.Address.ToString() + "\t\t" + peer.Version + "\t\t" + peer.IsConnected + "\t\t" + peer.NumberOfBlocks + "\t\t" + peer.verack).OrderBy(o => o).ToArray();
                foreach (var a in list)
                {
                    Console.WriteLine(a);
                }
                //}
            }
            while (true);
#endif
        }
    }
}
